<script lang="ts" setup>
import { ref, reactive, computed } from 'vue'
import CustomFormItem from '@/components/basic/CustomFormItem.vue'
import { getToken } from '@/utils/cache/cookies'
import { queryShortTermDetail } from '@/api/order'
import { otherChargeRefund, shortTermChargeRefund } from '@/api/expense'
import { queryShortTermDetailResponseData } from '@/api/order/types/order'
import {
  ElMessage,
  FormInstance,
  FormRules,
  UploadFile,
  UploadFiles,
  UploadUserFile
} from 'element-plus'
import { validatePhone } from '@/utils/formvalidate'
import { queryUserInfoDetailOrder } from '@/api/user'
import { bikeShortTermDetailOrderTableCol } from '@/api/user/types/user'
import { ShortTermAdjustType } from '@/types/enum'

/** 普通新建   open --> 输入phone 执行blur 查询queryUserInfoDetailOrder --> 选择 --> orderIdInfo 分割 并得到当前订单data数据  提交/取消 清空()  -->   */
const dialogVisible = ref<boolean>(false)
const isCreated = ref<boolean>(true)
const startTime = ref<string>('')
const endTime = ref<string>('')
const phoneDisabled = ref<boolean>(false)
const orderIdDisabled = ref<boolean>(false)
const orderIdInfoReg = new RegExp(/\d*/)
const timeReg = new RegExp(/(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})/g)
const open = () => {
  /** 是否新建 */
  if (!isCreated.value) {
    /** 不是新建 则 */
    getShortTermDetail()
  } else {
    data.value = null
  }
  dialogVisible.value = true
}
const setId = (newId: string, newPhone: string, newStartTime: string, newEndTime: string) => {
  form.orderId = newId
  form.phone = newPhone
  startTime.value = newStartTime
  endTime.value = newEndTime
  phoneDisabled.value = true
  orderIdDisabled.value = true
  orderIdInfo.value = `${form.orderId} (${startTime.value}-${endTime.value})`
  isCreated.value = false
}
const getShortTermDetail = async () => {
  formLoading.value = true
  try {
    const res = await queryShortTermDetail({
      token: getToken() ?? '',
      orderId: form.orderId
    })
    if (res.statusCode === '0') {
      data.value = res.data
    }
    formLoading.value = false
  } catch (error) {
    console.error(error)
    formLoading.value = false
  }
}
defineExpose({ open, setId, getShortTermDetail })

/**
 * @param type - 退费类型
 * @param operateType - 操作类型
 */
const form = reactive({
  phone: '',
  orderId: '',
  operateType: 0,
  type: 0,
  reason: '',
  applyAmount: 0,
  couponReturn: 0,
  imageUrls: ''
})
const formRef = ref<FormInstance | null>(null)
const validateMoney = (rule: any, value: any, callback: any) => {
  const moneyReg = /^(0|[1-9]\d*)(\.\d+)?$/
  if (!value) {
    return callback(new Error('请输入金额'))
  }
  if (!Number.isFinite(+value)) {
    return callback(new Error('请输入数字值'))
  }
  if (!moneyReg.test(value)) {
    return callback(new Error('金额不能为负数'))
  }
  if (value.toString().split('.').length === 2) {
    if (value.toString().split('.')[1].length > 2)
      return callback(new Error('金额小数点后不超过两位'))
  }
  setTimeout(() => {
    if (form.operateType === 1) return callback()
    if (value <= (maxReturn.value ?? 0)) {
      callback()
    } else {
      callback(new Error('最多可退' + maxReturn.value))
    }
  }, 100)
}

const rules = reactive<FormRules>({
  phone: [{ required: true, validator: validatePhone }],
  orderId: [{ required: true, message: '请选择行程编号', trigger: 'blur' }],
  operateType: [{ required: true, message: '请选择操作类型', trigger: 'change' }],
  type: [{ required: true, message: '请选择收/退费类型', trigger: 'change' }],
  applyAmount: [{ required: true, validator: validateMoney }],
  reason: [{ required: true, message: '请输入原因', trigger: 'blur' }]
})
const loading = ref<boolean>(false)
const formLoading = ref<boolean>(false)
const orderData = ref<bikeShortTermDetailOrderTableCol[]>([])
const data = ref<queryShortTermDetailResponseData | null>(null)
const fileList = ref<UploadUserFile[]>([])
const UploadHeader = reactive({
  Authorization: getToken() ?? ''
})
const href = ref<string>(import.meta.env.VITE_API + 'uploadOtherChargeImages')
const getUserDetailInfo = async () => {
  try {
    loading.value = true
    const res = await queryUserInfoDetailOrder({
      token: getToken() ?? '',
      phone: form.phone,
      selectType: 'bikeShortTerm',
      type: '',
      orderId: form.orderId
    })
    if (res.statusCode === '0') {
      orderData.value = res.data.list as bikeShortTermDetailOrderTableCol[]
    }
    loading.value = false
  } catch (error) {
    console.error(error)
    loading.value = false
  }
}

const orderIdInfo = ref<string>('')
const handleOrderIdChange = () => {
  data.value = null
  const arr2 = orderIdInfo.value.match(orderIdInfoReg) ?? ['']
  form.orderId = arr2[0]
  const arr = orderIdInfo.value.match(timeReg) ?? ['', '']
  startTime.value = arr[0]
  endTime.value = arr[1]
  getShortTermDetail()
}
const handlePhoneBlur = () => {
  if (!form.phone) return

  getUserDetailInfo()
}

/** 金额禁用 */
const amountDisabed = computed(() =>
  !form.operateType ? (data.value?.waitPayAmount ? true : false) : false
)
/** 操作类型 收费label */
const operateTypeFeeLabel = computed(() => (isCreated.value ? '收费(骑行费)' : '收费'))
/**  收退费类型的label */
const typeLabel = computed(() => (form.operateType && !isCreated.value ? '收费类型' : '退费类型'))
/** 控制 收退费类型的 违规费 拖车费 维修费 的显示 */
const isShowOtherFee = computed(() => !isCreated.value)
/** 控制  强制还车费的显示 */
const isShowDispatchFee = computed(() => !form.operateType)
/** 是否有强制还车费 */
const isHasDispatchFee = computed(() => Number(data.value?.dispatchFee))
/** 是否有维修费 */
const isHasRepairFee = computed(() => Number(data.value?.repairFee))
/** 是否有拖车费 */
const isHasTowingFee = computed(() => Number(data.value?.towingFee))
/** 是否有违规费 */
const isHasViolationFee = computed(() => Number(data.value?.violationFee))
const isCharge = computed(() => operateTypeFeeLabel.value === '收费' && form.operateType === 1)
/** 控制强制还车费的禁用 */
const isDisabledDispatchFee = computed(() => !!isHasDispatchFee.value && isCharge.value)

/** 控制维修费的禁用 */
const isDisabledRepairFee = computed(() => !!isHasRepairFee.value || !isCharge.value)
/** 控制拖车费的禁用 */
const isDisabledTowingFee = computed(() => !!isHasTowingFee.value || !isCharge.value)
/** 控制违规费的禁用 */
const isDisabledViolationFee = computed(() => !!isHasViolationFee.value || !isCharge.value)
/** 是否已支付完成 */
const isPay = computed(() => Number(data.value?.waitPayAmount))
/** 抵扣方式是否包括优惠券/折扣券 */
const isHasCoupon = computed(() => /[优惠券|折扣券]/.test(data.value?.deductionType ?? ''))
const isChargeOtherFee = computed(
  () => isCharge.value && (form.type === 2 || form.type === 3 || form.type === 4)
)
/** 短租订单最多可退费用 根据选择的退费类型更改 */
const maxReturn = computed(() => {
  if (form.operateType) return 0
  if (form.type === 0) {
    return data.value?.refundRent
  } else if (form.type === 1) {
    return data.value?.refundDispatchFee
  } else if (form.type === 2) {
    return data.value?.refundRepairFee
  } else if (form.type === 3) {
    return data.value?.refundTowingFee
  } else if (form.type === 4) {
    return data.value?.refundViolationFee
  } else {
    return 0
  }
})
const allIn = () => {
  form.applyAmount = maxReturn.value ?? 0
}
/** 提交 */
const emits = defineEmits(['refresh'])
const handleFileSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  form.imageUrls = uploadFiles
    .map((file: UploadFile) => (file.response as ApiResponseData<string>).data)
    .join(',')
}
const handleRemove = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  form.imageUrls = uploadFiles
    .map((file: UploadFile) => (file.response as ApiResponseData<string>).data)
    .join(',')
}
const handleExeed = () => {
  ElMessage.warning('相关图片仅支持上传2张')
}
const submit = () => {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      isChargeOtherFee.value ? otherCharge() : shortTermCharge()
    }
  })
}
const shortTermCharge = async () => {
  try {
    const res = await shortTermChargeRefund({
      token: getToken() ?? '',
      orderId: form.orderId,
      operateType: form.operateType as 0 | 1,
      type: form.type as ShortTermAdjustType,
      reason: form.reason,
      applyAmount: form.applyAmount,
      couponReturn: form.couponReturn as 0 | 1
    })
    if (res.statusCode === '0') {
      ElMessage.success(res.data)
      dialogVisible.value = false
      emits('refresh')
    }
  } catch (error) {
    console.error(error)
  }
}
const otherCharge = async () => {
  try {
    const res = await otherChargeRefund({
      orderId: form.orderId,
      applyAmount: form.applyAmount,
      type: form.type as ShortTermAdjustType,
      operateType: form.operateType as 0 | 1,
      imageUrls: form.imageUrls,
      reason: form.reason,
      token: getToken() ?? ''
    })
    if (res.statusCode === '0') {
      ElMessage.success(res.data)
      emits('refresh')
      dialogVisible.value = false
    }
  } catch (error) {
    console.error(error)
  }
}
/** 清空 */
const handleClose = () => {
  formRef.value?.resetFields()
  startTime.value = ''
  endTime.value = ''
  orderData.value = []
  orderIdInfo.value = ''
  phoneDisabled.value = false
  orderIdDisabled.value = false
  isCreated.value = true
  fileList.value = []
}
const cancle = () => {
  dialogVisible.value = false
}
</script>

<template>
  <el-dialog v-model="dialogVisible" width="850" title="短租收/退费" @close="handleClose">
    <el-form :model="form" :rules="rules" label-width="140px" ref="formRef" v-loading="formLoading">
      <el-form-item label="用户手机号" prop="phone">
        <el-input v-model="form.phone" @blur="handlePhoneBlur" :disabled="phoneDisabled" />
      </el-form-item>
      <el-form-item label="行程编号" prop="orderId">
        <el-select
          v-model="orderIdInfo"
          remote
          :remote-method="getUserDetailInfo"
          :loading="loading"
          @change="handleOrderIdChange"
          :disabled="orderIdDisabled"
        >
          <el-option
            :value="`${item.orderId} (${item.startTime}-${item.endTime})`"
            v-for="item in orderData"
            :key="item.orderId"
          >
            <template #default>
              <span
                >{{ item.orderId }}
                <span class="text-[#999999]">({{ item.startTime }} - {{ item.endTime }})</span>
              </span>
            </template>
          </el-option>
        </el-select>
      </el-form-item>
      <transition mode="out-in">
        <div v-if="data">
          <custom-form-item :label-width="140">
            <template #label>
              <span>骑行时长:</span>
            </template>
            <template #value>
              <span>{{ data?.rideDuration }}</span>
            </template>
            <template #label2>
              <span>骑行金额:</span>
            </template>
            <template #value2>
              <span>{{ data?.rent }}元</span>
            </template>
          </custom-form-item>
          <custom-form-item :label-width="140" :first-col="24">
            <template #label>
              <span>其他费用:</span>
            </template>
            <template #value>
              <span
                >{{ data?.repairFee + data?.towingFee + data?.violationFee }}元
                <span class="text-[12px] text-[#999999]"
                  >(拖车费{{ data?.towingFee }}+违规费{{ data?.violationFee }}+维修费{{
                    data?.repairFee
                  }})</span
                >
              </span>
            </template>
          </custom-form-item>
          <custom-form-item :label-width="140">
            <template #label>
              <span>抵扣方式:</span>
            </template>
            <template #value>
              <span>{{ data?.deductionType }}</span>
            </template>
            <template #label2 v-if="isHasDispatchFee">
              <span>强制还车费:</span>
            </template>
            <template #value2 v-if="isHasDispatchFee">
              <span class="text-[#FF6D75]">{{ data?.dispatchFee }}元</span>
            </template>
          </custom-form-item>
          <custom-form-item :label-width="140" :first-col="24">
            <template #label>
              <span>支付状态:</span>
            </template>
            <template #value>
              <span class="text-warning-light inline-flex" v-if="isPay"
                ><span>待支付{{ data?.waitPayAmount }}元</span>
                <span class="text-[12px] text-[#999999]">{{ data?.waitPayRemark }}</span>
              </span>
              <span v-else class="text-[#00A870]">已支付完成</span>
            </template>
          </custom-form-item>
          <el-form-item prop="operateType" label="操作">
            <el-radio-group v-model="form.operateType">
              <el-radio label="退费" :value="0" />
              <el-radio :label="operateTypeFeeLabel" :value="1" />
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="type" :label="typeLabel">
            <el-radio-group v-model="form.type">
              <el-radio label="骑行费" :value="0" :key="0" />
              <TransitionGroup name="list">
                <template v-if="isShowOtherFee">
                  <el-radio label="维修费" :value="2" :key="2" :disabled="isDisabledRepairFee" />
                  <el-radio label="拖车费" :value="3" :key="3" :disabled="isDisabledTowingFee" />
                  <el-radio label="违规费" :value="4" :key="4" :disabled="isDisabledViolationFee" />
                </template>
                <el-radio
                  v-if="isShowDispatchFee"
                  :disabled="isDisabledDispatchFee"
                  label="强制还车费"
                  :value="1"
                  :key="1"
                />
              </TransitionGroup>
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="applyAmount" label="金额">
            <el-input v-model="form.applyAmount" type="number" :disabled="amountDisabed">
              <template #prepend>￥</template>
            </el-input>
            <span
              class="text-[12px] text-[#999999] leading-17 mt-5"
              v-if="data?.waitPayAmount && !form.operateType"
            >
              有待支付金额的请优先前往用户信息详情-短租消费中找到对应的行程修改待支付金额
            </span>
            <span class="text-[12px] text-[#999999] leading-17 mt-5" v-else-if="!form.operateType"
              >最多可退{{ maxReturn }},
              <span class="text-[#FF6D75] cursor-pointer" @click="allIn">全部填入;</span>
              <span
                >有待支付金额的请优先选择修改待支付金额;骑行费、强制还车费退还至用户余额,其他费用将原路退回</span
              >
            </span>
          </el-form-item>
          <el-form-item
            label="相关图片"
            prop="imageUrls"
            v-if="isChargeOtherFee"
            :rules="[{ required: true, message: '请上传相关图片', trigger: 'blur' }]"
          >
            <el-upload
              v-model:file-list="fileList"
              :limit="2"
              :headers="UploadHeader"
              :action="href"
              list-type="picture-card"
              :on-success="handleFileSuccess"
              :on-remove="handleRemove"
              :on-exceed="handleExeed"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
          </el-form-item>
          <el-form-item label="骑行费优惠/折扣券" v-if="isHasCoupon">
            <el-radio-group v-model="form.couponReturn">
              <el-radio label="不退回" :value="0" />
              <el-radio label="退回" :value="1" />
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="reason" label="原因">
            <el-input v-model="form.reason" :min="2" placeholder="请输入原因" type="textarea" />
          </el-form-item>
        </div>
      </transition>
    </el-form>
    <template #footer>
      <el-button @click="cancle" plain>取消</el-button>
      <el-button type="primary" @click="submit">提交</el-button>
    </template>
  </el-dialog>
</template>

<style scoped>
.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* 确保将离开的元素从布局流中删除
  以便能够正确地计算移动的动画。 */
.list-leave-active {
  position: absolute;
}
</style>
